<?php
require_once 'models/acl.inc';


class TJsonResponse extends TResponse {
    public function Url($controller = null,$method = null,array $parameters = array()){
        return $this->Application()->Url($this->service->Name(),array('controller'=>$controller,'method'=>$method) + $parameters);
    }
        
    protected function sendJson($v){
        $this->Headers = 'Cache-control:no-cache';
        $this->Headers = 'Expires:-100';
    	$this->Headers = 'Content-Type:text/javascript;charset=UTF-8';
        $this->SendHeaders();
        echo json_encode($v);
        die;
    }
    
    protected function valueToJson($v,$localize = false, $depth = 1,$level = 0){
         if ($v instanceof IItem)
             return $this->itemToJson ($v, $depth, $level + 1);
         if ($v instanceof Iterator){
             $temp = array();
             foreach ($v as $vi)
                $temp[] = $this->valueToJson($vi, $localize, $depth, $level + 1);
             return $temp;
         }
         if (is_numeric($v) && $localize)
         	return _n($v);
         if ($v instanceof TImage)
         	return (object)array('fullsize'=>$v->GetLink(),'thumbnail'=>$v->GetThumbnailLink());
         
         if ($v instanceof TFile)
         	return $v->GetLink();

         return (string)$v;
    }
    
    protected function itemPublishedProperties(IItem $item, &$c = null){
    	if (isset($this->service->PublishedProperties[$item->ClassName()])){
    		$c = $item->ClassName();
    		return $this->service->PublishedProperties[$item->ClassName()];
    	}
    	foreach ($this->service->PublishedProperties as $c => $props)
    		if (is_subclass_of($item->ClassName(), $c))
    			return $props;
    	return null;
    }
    
    protected function itemToJson(IItem $item,$depth = 1,$level = 0){
        $temp = array();
        $cn = null;
        if ($props = $this->itemPublishedProperties($item,$cn)){
            if ($item->Thumbnail){
                $temp['image'] = $item->Thumbnail->GetLink();
                $temp['thumbnail'] = $item->Thumbnail->GetThumbnailLink();
            }
            $temp['ItemId'] = $item->ItemId();
             
            foreach ($props as $pn){           	 
                if ($p = $item->Property($pn)){
                    switch ($p->Type()){
                        case TItemPropertyType::PT_IMAGE:$temp[$p->Name()] = (object)array('origin'=>$p->Value()->GetLink(),'thumbnail'=>$p->Value()->GetThumbnailLink());break;
                        case TItemPropertyType::PT_REFERENCE:{
                            $ri = $p->ReferedInstance();
                            if ($level < $depth)
                                $temp[$p->Name()] = $ri?$this->itemToJson($ri,$depth,$level + 1):null;
                            else 
                              						  $temp[$p->Name()] = (string)$ri;
                        }break;
                        case TItemPropertyType::PT_COLLECTION:{
                            $temp[$p->Name()] = array();
                            if ($level < $depth)
                            foreach ($p->Value() as $ci)
                                if (($level + 1) < $depth)
                                    $temp[$p->Name()][] = $this->itemToJson ($ci,$depth,$level + 1);
                                else
                                   						 $temp[$p->Name()][] = (string)$ci;
                        }break;
                        default:{
                        	if ($p->Value() instanceof IItem)
                        		$temp[$p->Name()] = $this->itemToJson($p->Value(),$depth,$level + 1);
                        	else	
                        						$temp[$p->Name()] = $this->valueToJson($p->Value(),isset($this->service->LocalizeProperties[$cn]) && in_array($pn,$this->service->LocalizeProperties[$cn]),$depth,$level + 1);
                        }break;
                    }
             	} else if ($pn == 'ClassName'){
             		$temp["ClassName"] = $item->ClassName();
             	} else if ($pn == 'URL'){
             		$temp["URL"] = $this->Application()->GetService('front')->ItemNavigationUrl($item);
                } else 
                   				 $temp[$pn] = $this->valueToJson($item->$pn,isset($this->service->LocalizeProperties[$item->ClassName()]) && in_array($pn,$this->service->LocalizeProperties[$item->ClassName()]),$depth,$level + 1);
            }
        }
        return (object)$temp;
    }
        
    public function http_ItemUrl($class,$id,$slug){
    	$this->sendJson($this->Application()->GetService('front')->RawItemNavigationUrl($class,$id,$slug));
    }
    
    public function http_CartPositions(){
    	$positions = $this->Service()->Cart->Positions();
    	$result = array();
    	foreach ($positions as $p)
    		$result[] = $this->itemToJson($p,2);
    	$this->sendJson($result);
    }
    
    public function http_AddToCart($product, array $options = array()){
    	$this->Service()->Cart->AddPosition($product, $options);
    	$this->http_CartPositions();
    }
    
    public function http_RemoveFromCart($id){
    	$this->Service()->Cart->DeletePosition($id);
    	$this->http_CartPositions();
    }
    
    public function http_ClearCart(){
    	$this->Service()->Cart->MakeEmpty();
    	$this->http_CartPositions();
    }
}

/**
 * 
 * @author kras
 *
 * @property TCart $Cart
 */

class TJsonService extends TService {
/**
 * @var TCart
 */	
	protected $_ioc_cart_;
	
/**
 * @var IKeyValueRepository
 */
	protected $_ioc_shop_settings_;
	
	
	private $_published_properties_ = array();
	private $_localize_properties_ = array();
	
	public function __set($nm,$value){
		switch ($nm){
			case 'PublishedProperties':$this->_published_properties_ = TConvertions::ConvertToArray($value, array(';','=',','), array(false,true,false));break;
			case 'LocalizeProperties':$this->_localize_properties_ = TConvertions::ConvertToArray($value, array(';','=',','), array(false,true,false));break;
			default:parent::__set($nm, $value);break;
		}
	}
	
	public function __get($nm){
		switch ($nm){
			case 'PublishedProperties':return $this->_published_properties_;break;
			case 'LocalizeProperties':return $this->_localize_properties_;break;
			default:return parent::__get($nm);break;
		}
	}	
	
    protected function handleRequest(TRequest $request){
        $r = new TJsonResponse($this,'json_data');
        $this->Cart->Response = $r;
        $r->Handle($request);
        return true;
    }
	
    /**
    * Checks request object
    * @param TRequest $request
    * @return boolean
    */
    protected function checkRequest(TRequest $request){
        return $request;
    }
}